package io.xxx.omni.sync.impl

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject
import io.xxx.omni.sync.Document
import io.xxx.omni.sync.PagePorter
import io.xxx.omni.sync.Store
import io.xxx.omni.util.dateTimeFormatter
import io.xxx.omni.util.toLocalDateTime
import org.apache.commons.codec.digest.DigestUtils
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
import java.time.LocalDateTime
import java.util.*

/**
 * 丁香医生
 */
abstract class DxYsPorter : PagePorter() {

    val httpUrl = "https://mama.dxy.com/japi/platform/201029020"

    override val platformCode = "dingxiangyisheng"

    protected abstract val method: String

    protected fun getResponse(
        store: Store,
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        pageNo: Long = 1
    ): JSONObject {
        val params = getParams(startTime, endTime, pageNo)
        val signMap = TreeMap(params)
        val paramsJson = JSON.toJSONString(params)
        signMap["method"] = method
        signMap["bizcontent"] = paramsJson
        signMap["appkey"] = store.appKey!!
        signMap["token"] = store.accessToken!!
        val builder = StringBuilder().append(store.appSecret)
            .append("appKey").append(store.appKey)
            .append("bizcontent").append(paramsJson)
            .append("method").append(method)
            .append("token").append(store.accessToken)
            .append(store.appSecret)
        val sign = DigestUtils.md5Hex(builder.toString())
        signMap["sign"] = sign
        val response = restTemplate.postForEntity(httpUrl, signMap, JSONObject::class.java)
        if (response.statusCode.isError || response.body == null) {
            val msg = "接口[method: $method, queryParams: $signMap]异常"
            throw RuntimeException(msg)
        }
        val body = response.body!!
        if (!body.getString("code").equals("0")) {
            val msg = "接口[method: $method, queryParams: $signMap]异常: $body"
            log.error(msg)
            throwException(method, null, body.getString("message"))
        }
        return response.body!!
    }

    protected abstract fun getParams(
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        pageNo: Long = 1
    ): Map<String, String>

    companion object {
        private val log = LoggerFactory.getLogger(DxYsPorter::class.java)
    }
}

@Component
class DxYsTradePorter : DxYsPorter() {

    override val method = "Differ.JH.Business.GetOrder"

    override val jobId = 1

    override fun getCount(store: Store, startTime: LocalDateTime, endTime: LocalDateTime, parameter: Any?): Long? {
        val response = getResponse(store, startTime, endTime)
        return response.getLong("numtotalorder")
    }

    override fun getData(
        store: Store,
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        parameter: Any?,
        pageNo: Long,
    ): List<Document>? {
        val response = getResponse(store, startTime, endTime)
        return response.getJSONArray("orders").map {
            @Suppress("unchecked_cast")
            val value = JSONObject(it as Map<String, Any>)
            Document(
                value.getString("PlatOrderNo"),
                value,
                value.getString("tradetime").toLocalDateTime()
            )
        }
    }

    override fun getParams(startTime: LocalDateTime, endTime: LocalDateTime, pageNo: Long): Map<String, String> {
        return mapOf(
            "OrderStatus" to "JH_99",
            "TimeType" to "JH_01",
            "StartTime" to startTime.format(dateTimeFormatter),
            "EndTime" to endTime.format(dateTimeFormatter),
            "PageIndex" to pageNo.toString(),
            "PageSize" to pageSize.toString(),
        )
    }
}